package com.wuzheng.wisgo.sanitation.cloud.service.job.impl;

import com.baomidou.mybatisplus.plugins.Page;
import com.wuzheng.wisgo.sanitation.cloud.constant.Constants;
import com.wuzheng.wisgo.sanitation.cloud.constant.ErrorConst;
import com.wuzheng.wisgo.sanitation.cloud.enums.InfixDataEnum;
import com.wuzheng.wisgo.sanitation.cloud.model.job.param.JobRoadDetailParam;
import com.wuzheng.wisgo.sanitation.cloud.model.job.pojo.JobRoadDTO;
import com.wuzheng.wisgo.sanitation.cloud.model.job.param.JobRoadListParam;
import com.wuzheng.wisgo.sanitation.cloud.model.road.RoadStateDTO;
import com.wuzheng.wisgo.sanitation.cloud.repository.entity.job.JobRoad;
import com.wuzheng.wisgo.sanitation.cloud.repository.entity.person.User;
import com.wuzheng.wisgo.sanitation.cloud.repository.entity.plan.JobPlanRoad;
import com.wuzheng.wisgo.sanitation.cloud.repository.mapper.job.JobRoadMapper;
import com.wuzheng.wisgo.sanitation.cloud.service.job.JobRoadService;
import com.wuzheng.wisgo.sanitation.cloud.service.plan.JobPlanRoadService;
import com.wuzheng.wisgo.sanitation.framework.base.service.impl.BaseServiceImpl;
import com.wuzheng.wisgo.sanitation.framework.core.constant.SysRespEnum;
import com.wuzheng.wisgo.sanitation.framework.core.util.ServiceAssert;
import com.wuzheng.wisgo.sanitation.framework.util.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

/**
 * @author：hoipang
 * @date：Created in 2019-12-10
 * @description：作业道路服务实现类
 * @modified By：
 * @version: 1.0
 */
@Service
public class JobRoadServiceImpl extends BaseServiceImpl<JobRoad> implements JobRoadService {
    @Resource
    JobPlanRoadService jobPlanRoadService;

    @Override
    public List<JobRoadDTO> listJobRoadDTOs(User user, JobRoadListParam jobRoadListParam) {
        JobRoadMapper jobRoadMapper = this.getMapper(JobRoadMapper.class);
        List<JobRoadDTO> list;

        if (jobRoadListParam.getPageSize() != null && jobRoadListParam.getPageIndex() != null) {
            Page<JobRoadDTO> page = new Page<>(jobRoadListParam.getPageIndex(), jobRoadListParam.getPageSize());
            list = jobRoadMapper.pageJobRoadDTOs(page, Constants.EMPYT_STRING, jobRoadListParam.getRouteName(),
                    jobRoadListParam.getLaneType());

            if (list != null && !list.isEmpty()) {
                list.forEach(m -> {
                    m.setDeptName(user.getCustomerName());

                    int jobTypeCount = 0;
                    if (StringUtils.isNotBlank(m.getJobType())) {
                        jobTypeCount = m.getJobType().split(",").length > 1 ? 2 : 1;
                    }

                    String[] gpsList = simulationData(jobTypeCount,m.getStatus(),m.getGpsFeatures());
                    m.setGpsFeatures(gpsList);
                });
            }
            return list;
        }
        list = jobRoadMapper.listJobRoadDTOs(Constants.EMPYT_STRING, jobRoadListParam.getRouteName(), jobRoadListParam.getLaneType());

        if (list != null && !list.isEmpty()) {
            list.forEach(m -> {
                int jobTypeCount = 0;
                if (StringUtils.isNotBlank(m.getJobType())) {
                    jobTypeCount = m.getJobType().split(",").length > 1 ? 2 : 1;
                }

                m.setDeptName(user.getCustomerName());

                String[] gpsList = simulationData(jobTypeCount,m.getStatus(),m.getGpsFeatures());
                m.setGpsFeatures(gpsList);
            });
        }
        return list;
    }

    @Override
    public List<RoadStateDTO> listRoadStateDTOs() {
        JobRoadMapper jobRoadMapper = this.getMapper(JobRoadMapper.class);
        List<RoadStateDTO> list = jobRoadMapper.listRoadStateDTOs();

        list.forEach(m -> {
            int jobTypeCount = 0;
            if (StringUtils.isNotBlank(m.getJobType())) {
                jobTypeCount = m.getJobType().split(",").length > 1 ? 2 : 1;
            }
            String[] gpsList = simulationData(jobTypeCount,m.getStatus(),m.getGpsStatus());
            m.setGpsStatus(gpsList);
        });
        return list;
    }

    @Override
    public void removeJobRoads(List<String> list) {
        ServiceAssert.isTrue(list != null && !list.isEmpty(), SysRespEnum.ILLEGAL_ARGUMENT.getCode(),
                ErrorConst.Common.ARGUMENT_NOT_NULL);

        List<JobPlanRoad> relationList = jobPlanRoadService.list(list);
        ServiceAssert.isTrue(relationList == null || relationList.isEmpty(), SysRespEnum.SERVICE_EXCEPTION.getCode(),
                ErrorConst.Common.REMOVE_RELATION);

        List<JobRoad> jobRoadList = new ArrayList<>();
        list.forEach(id -> {
            JobRoad jobRoad = new JobRoad();
            jobRoad.setId(id);
            jobRoad.setDeFlag(true);
            jobRoadList.add(jobRoad);
        });
        this.updateBatchById(jobRoadList, jobRoadList.size());
    }

    @Override
    public JobRoadDTO selectJobRoadDTO(User user, String id) {
        ServiceAssert.isTrue(StringUtils.isNotBlank(id), SysRespEnum.ILLEGAL_ARGUMENT.getCode(),
                ErrorConst.Common.ARGUMENT_NOT_NULL);

        JobRoadMapper jobRoadMapper = this.getMapper(JobRoadMapper.class);

        JobRoadDTO jobRoadDTO = jobRoadMapper.selectJobRoadDTO(id, Constants.EMPYT_STRING, Constants.EMPYT_STRING);
        ServiceAssert.isTrue(jobRoadDTO != null, SysRespEnum.SERVICE_EXCEPTION.getCode(),
                ErrorConst.Common.QUERY_RESULT_NOT_EXIST);
        jobRoadDTO.setDeptName(user.getCustomerName());

        int jobTypeCount = 0;
        if (StringUtils.isNotBlank(jobRoadDTO.getJobType())) {
            jobTypeCount = jobRoadDTO.getJobType().split(",").length > 1 ? 2 : 1;
        }

        String[] gpsList = simulationData(jobTypeCount,jobRoadDTO.getStatus(),jobRoadDTO.getGpsFeatures());
        jobRoadDTO.setGpsFeatures(gpsList);
        return jobRoadDTO;
    }


    //TODO 模拟数据
    private String[] simulationData(int jobTypeCount, String status, String[] gpsFeatures) {
        StringBuilder sb = new StringBuilder();
        List<String> itemList = new ArrayList<>(Arrays.asList(gpsFeatures));
        List<String> gpsList = new ArrayList<>();
        String[] gpsArray = new String[gpsList.size()];
        switch (status) {
            case "unfinished":
                for (String c1 : itemList) {
                    sb.delete(0, sb.length());
                    String[] arrayStr = c1.split(";");
                    for (String s : arrayStr) {
                        String newStr;
                        switch (jobTypeCount) {
                            case 1:
                                newStr = s.concat(",").concat("0;");
                                break;
                            case 2:
                                newStr = s.concat(",").concat("0").concat(",").concat("0;");
                                break;
                            default:
                                newStr = s;
                                break;
                        }
                        sb.append(newStr);
                    }
                    gpsList.add(sb.toString());
                }
                break;
            case "finished":
                for (String c : itemList) {
                    sb.delete(0, sb.length());
                    String[] arrayStr = c.split(";");
                    for (String s : arrayStr) {
                        String newStr;
                        switch (jobTypeCount) {
                            case 1:
                                newStr = s.concat(",").concat("1;");
                                break;
                            case 2:
                                newStr = s.concat(",").concat("1").concat(",").concat("1;");
                                break;
                            default:
                                newStr = s;
                                break;
                        }
                        sb.append(newStr);
                    }
                    gpsList.add(sb.toString());
                }
                break;
            default:
                int count = 0;
                for (int i = 0; i < itemList.size(); i++) {
                    int itemCount = itemList.get(i).split(";").length;
                    count += itemCount;
                }
                Random random = new Random();
                int max = random.nextInt(count);
                if (max == 0) {
                    max = 2;
                }

                for (int j = 0; j < itemList.size(); j++) {
                    sb.delete(0, sb.length());
                    String[] arrayStr = itemList.get(j).split(";");
                    for (int index = 0, len = arrayStr.length; index < len; index++) {
                        if (max > 0) {
                            String newStr;
                            switch (jobTypeCount) {
                                case 1:
                                    newStr = arrayStr[index].concat(",").concat("1;");
                                    break;
                                case 2:
                                    newStr = arrayStr[index].concat(",").concat("1").concat(",").concat("1;");
                                    break;
                                default:
                                    newStr = arrayStr[index];
                                    break;
                            }
                            sb.append(newStr);
                            max--;
                        }
                        if (max == 0) {
                            String newStr;

                            switch (jobTypeCount) {
                                case 1:
                                    newStr = arrayStr[index].concat(",").concat("0;");
                                    break;
                                case 2:
                                    newStr = arrayStr[index].concat(",").concat("0").concat(",").concat("1;");
                                    break;
                                default:
                                    newStr = arrayStr[index];
                                    break;
                            }
                            sb.append(newStr);
                        }
                    }
                    gpsList.add(sb.toString());
                }
                break;
        }
        return gpsList.toArray(gpsArray);
    }

    @Override
    public JobRoadDTO insertOrUpdate(User user, JobRoadDetailParam jobRoadDetailParam) {
        JobRoad jobRoad = new JobRoad();
        jobRoad.setCustomerId(jobRoadDetailParam.getCustomerId());
        jobRoad.setRoadName(jobRoadDetailParam.getName());
        jobRoad.setRoadStart(jobRoadDetailParam.getStartName());
        if (StringUtils.isNotBlank(jobRoadDetailParam.getStartLong())) {
            jobRoad.setRoadStartLong(Double.valueOf(jobRoadDetailParam.getStartLong()));
        }
        if (StringUtils.isNotBlank(jobRoadDetailParam.getStartLat())) {
            jobRoad.setRoadStartLat(Double.valueOf(jobRoadDetailParam.getStartLat()));
        }
        jobRoad.setRoadEnd(jobRoadDetailParam.getEndName());
        if (StringUtils.isNotBlank(jobRoadDetailParam.getEndLong())) {
            jobRoad.setRoadEndLong(Double.valueOf(jobRoadDetailParam.getEndLong()));
        }
        if (StringUtils.isNotBlank(jobRoadDetailParam.getEndLat())) {
            jobRoad.setRoadEndLat(Double.valueOf(jobRoadDetailParam.getEndLat()));
        }
        if (StringUtils.isNotBlank(jobRoadDetailParam.getLength())) {
            jobRoad.setRoadLength(Double.valueOf(jobRoadDetailParam.getLength()));
        }
        if (StringUtils.isNotBlank(jobRoadDetailParam.getWidth())) {
            jobRoad.setRoadWidth(Double.valueOf(jobRoadDetailParam.getWidth()));
        }
        jobRoad.setLaneTypeId(jobRoadDetailParam.getLaneType());
        jobRoad.setLaneType(jobRoadDetailParam.getLaneTypeName());
        jobRoad.setGpsFeatures(jobRoadDetailParam.getGpsFeatures());
        jobRoad.setGpsOffset(jobRoadDetailParam.getGpsOffset());
        jobRoad.setRemark(jobRoadDetailParam.getRemark());

        String method = StringUtils.isBlank(jobRoadDetailParam.getMethod()) ? "" : jobRoadDetailParam.getMethod().toLowerCase();

        Boolean update = method.equals(InfixDataEnum.UPDATE.getTypeId()) && StringUtils.isNotBlank(jobRoadDetailParam.getId());
        Boolean flag = update || method.equals(InfixDataEnum.ADD.getTypeId());
        ServiceAssert.isTrue(flag, SysRespEnum.ILLEGAL_ARGUMENT.getCode(), SysRespEnum.ILLEGAL_ARGUMENT.getMessage());

        if (method.equals(InfixDataEnum.ADD.getTypeId())) {
            jobRoad.setDeFlag(false);
            jobRoad.setCreator(user.getName());
            jobRoad.setCreateTime(new Date());
            this.insert(jobRoad);
        }
        String roadId = StringUtils.isBlank(jobRoadDetailParam.getId()) ? jobRoad.getId() : jobRoadDetailParam.getId();

        if (method.equals(InfixDataEnum.UPDATE.getTypeId())) {
            jobRoad.setId(roadId);
            jobRoad.setModifier(user.getName());
            jobRoad.setModifyTime(new Date());
            this.updateById(jobRoad);
        }
        JobRoadDTO roadDetailDTO = this.selectJobRoadDTO(user, roadId);
        return roadDetailDTO;
    }
}
